package com.Touch.tuio {

	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.geom.Point;
	
	//
	// 定义一个触摸点类，其实在这个类里面注意一下传进来的参数o
	// 它是这个类的一个关键，也是整个lib的一个关键，由它来dispatcher
	// 所有的touch事件，当然也是它来响应touch事件
	// 
	public class TUIOObject 
	{
		public var x:Number;//当前位置	
		public var y:Number;
		
		public var oldX:Number;//原有位置
		public var oldY:Number;
		
		public var dX:Number;
		public var dY:Number;				
		
		public var area:Number;
		
		public var TUIOClass:String;		// cur or Obj.. 
		public var sID:int;
		public var ID:int;
		public var angle:Number;		
		public var pressure:Number;
		
		private var isNew:Boolean;
		public var isAlive:Boolean;		
		public var obj:DisplayObject;
		public var spr:Sprite;
		public var trlx:Sprite;
		
		//public var color:int;
		
		private var aListeners:Array;

		public function TUIOObject (cls:String, id:int, px:Number, py:Number, dx:Number, dy:Number, sid:int = -1, ang:Number = 0, o:DisplayObject= null)
		{
			aListeners = new Array();
			TUIOClass = cls;
			ID = id;
			x = px;
			y = py;
			oldX = px;
			oldY = py;
			dX = dx;
			dY = dy;
			sID = sid;
			angle = ang;
			isAlive = true;

			try {
				obj = o;
			} catch (e:Error)
			{
				obj = null;
			}
			
			isNew = true;
		}
		
		//
		// 当第一次创建一个TUIOObject对象时，需要发送TUIO_DOWN和TUIO_OVER事件
		//
		public function notifyCreated():void
		{
			if(obj)
			{
				try
				{
					// 将对象舞台坐标转化为显示对象坐标
					var localPoint:Point = obj.parent.globalToLocal(new Point(x, y));				
					//trace("Down : " + localPoint.x + "," + localPoint.y);
					
					// 分别dispatcher TUIO_OVER和TUIO_DOWN事件
					obj.dispatchEvent(new TUIOEvent(TUIOEvent.TUIO_OVER, true, false, x, y, localPoint.x, localPoint.y, 0, 0, obj, false,false,false, true, 0, TUIOClass, ID, sID, angle));													
					obj.dispatchEvent(new TUIOEvent(TUIOEvent.TUIO_DOWN, true, false, x, y, localPoint.x, localPoint.y, 0, 0, obj, false,false,false, true, 0, TUIOClass, ID, sID, angle));									
				} catch (e:Error)
				{
					obj = null;
				}
			}			
		}
		
		// 调用这个函数，说明在TUIOObject数组中存在当前点，也即是当前点移动了。
		public function setObjOver(o:DisplayObject):void
		{
			try {
				
				if(obj == null)
				{
					obj = o;				
					if(obj) 
					{
						// 当已存在TUIOObject对象，而obj对象为空时，需要将当前对象传递进来的显示对象
						//（也即是当前点下面最上层显示对象，是事件的发送者，事件也是产生于它），故需要
						// 赋值给obj对象，并dispatcher TUIO_OVER事件
						var localPoint:Point = obj.parent.globalToLocal(new Point(x, y));				
						obj.dispatchEvent(new TUIOEvent(TUIOEvent.TUIO_OVER, true, false, x, y, localPoint.x, localPoint.y, 0, 0, obj, false,false,false, true, 0, TUIOClass, ID, sID, angle));					
					}
				} 
				else if(obj != o) 
				{
					// 当已存在TUIOObject对象，而obj对象与传递进来的显示对象不一致，说明当前点移动了，并且移出了
					// 原来的obj对象的显示范围，故需要对原来对象dispatcher TUIO_OUT事件
					var localPoint_2:Point = obj.parent.globalToLocal(new Point(x, y));								
					obj.dispatchEvent(new TUIOEvent(TUIOEvent.TUIO_OUT, true, false, x, y, localPoint_2.x, localPoint_2.y, 0, 0, obj, false,false,false, true, 0, TUIOClass, ID, sID, angle));
					
					if(o)
					{
						// 当已存在TUIOObject对象，而obj对象与传递进来的显示对象不一致,并且传递进来的也是非空显示对象，
						// 说明当前点移动了，并且移出了原来的obj对象的显示范围，故需要对当前对象dispatcher TUIO_OVER事件
						localPoint_2 = obj.parent.globalToLocal(new Point(x, y));
						o.dispatchEvent(new TUIOEvent(TUIOEvent.TUIO_OVER, true, false, x, y, localPoint_2.x, localPoint_2.y, 0, 0, obj, false,false,false, true, 0, TUIOClass, ID, sID, angle));
					}
					obj = o;								
				}
			} catch (e:Error)
			{
//				trace("ERROR " + e);
			}
		}
		
		// 将所有需要dispatcher的TUIOObject对象添加到数值中
		public function addListener(reciever:Object):void
		{
			aListeners.push(reciever);
		}
		
		// 从数组中删除非alive状态的TUIOObject对象
		public function removeListener(reciever:Object):void
		{
			for(var i:int = 0; i<aListeners.length; i++)
			{
				if(aListeners[i] == reciever)
					aListeners.splice(i, 1);
			}
		}		
		
		public function kill():void
		{
			//trace("Die " + ID);			
			var localPoint:Point;
			
			if(obj && obj.parent)
			{	
				// 将当前TUIOObject对象中的显示对象清除，并让当前点dispatcher TUIO_OUT和TUIO_UP事件
				localPoint = obj.parent.globalToLocal(new Point(x, y));				
				obj.dispatchEvent(new TUIOEvent(TUIOEvent.TUIO_OUT, true, false, x, y, localPoint.x, localPoint.y, 0, 0, obj, false,false,false, true, 0, TUIOClass, ID, sID, angle));				
				obj.dispatchEvent(new TUIOEvent(TUIOEvent.TUIO_UP, true, false, x, y, localPoint.x, localPoint.y, 0, 0, obj, false,false,false, true, 0, TUIOClass, ID, sID, angle));									
			}			
			obj = null;
			
			// 为什么要所有都TUIO_UP有点不理解
			for(var i:int=0; i<aListeners.length; i++)
			{
				localPoint = aListeners[i].parent.globalToLocal(new Point(x, y));				
				aListeners[i].dispatchEvent(new TUIOEvent(TUIOEvent.TUIO_UP, true, false, x, y, localPoint.x, localPoint.y, 0, 0, aListeners[i], false,false,false, true, 0, TUIOClass, ID, sID, angle));								
			}
		}
		
		// 这个有点不理解
		public function notifyMoved():void
		{
			var localPoint:Point;
			for(var i:int=0; i<aListeners.length; i++)
			{
				//trace("Notify moved");
				localPoint = aListeners[i].parent.globalToLocal(new Point(x, y));				
				aListeners[i].dispatchEvent(new TUIOEvent(TUIOEvent.TUIO_MOVE, true, false, x, y, localPoint.x, localPoint.y, 0, 0, aListeners[i], false,false,false, true, 0, TUIOClass, ID, sID, angle));								
			}			
		}
	}
}